/**
 * Copyright (c) 2006-2016 Huize Ltd. All Rights Reserved. 
 *  
 * This code is the confidential and proprietary information of   
 * Hzins. You shall not disclose such Confidential Information   
 * and shall use it only in accordance with the terms of the agreements   
 * you entered into with Huize,http://www.huize.com.
 *  
 */
package com.agan.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/**
 * @author hz1412988
 * @date 2018年2月8日 上午10:29:31
 * @version
 */
public class FutureTaskForMultiCompute {

    public static void main(String[] args) {

	FutureTaskForMultiCompute inst = new FutureTaskForMultiCompute();
	// 创建任务集合
	List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>();
	// 创建线程池
	ExecutorService exec = Executors.newFixedThreadPool(5);
	for (int i = 0; i < 10; i++) {
	    // 传入Callable对象创建FutureTask对象
	    FutureTask<Integer> ft = new FutureTask<Integer>(inst.new ComputeTask(i, "" + i));
	    taskList.add(ft);
	    // 提交给线程池执行任务，也可以通过exec.invokeAll(taskList)一次性提交所有任务;
	    exec.submit(ft);
	}

	System.out.println("所有计算任务提交完毕, 主线程接着干其他事情！");

	// 开始统计各计算线程计算结果
	Integer totalResult = 0;
	for (FutureTask<Integer> ft : taskList) {
	    try {
		// FutureTask的get方法会自动阻塞,直到获取计算结果为止
		totalResult = totalResult + ft.get();
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    } catch (ExecutionException e) {
		e.printStackTrace();
	    }
	}

	// 关闭线程池
	exec.shutdown();
	System.out.println("多任务计算后的总结果是:" + totalResult);

    }

    private class ComputeTask implements Callable<Integer> {

	private Integer result = 0;

	private String taskName = "";

	public ComputeTask(Integer iniResult, String taskName) {
	    result = iniResult;
	    this.taskName = taskName;
	    System.out.println("生成子线程计算任务: " + taskName);
	}

	public String getTaskName() {
	    return this.taskName;
	}

	@Override
	public Integer call() throws Exception {
	    // TODO Auto-generated method stub

	    for (int i = 0; i < 100; i++) {
		result = +i;
	    }
	    // 休眠5秒钟，观察主线程行为，预期的结果是主线程会继续执行，到要取得FutureTask的结果是等待直至完成。
	    Thread.sleep(5000);
	    System.out.println("子线程计算任务: " + taskName + " 执行完成!");
	    return result;
	}
    }

}
